package ast.stmt;

import icg.EQLabel;
import icg.Quadruple;
import ts.SymbolTable;
import ast.Node;
import ast.exp.Expression;
import ast.type.Type;

public class WhileStmt extends Statement {
	private Expression exp;
	private Statement seq;
	public static EQLabel breakL;
	public static EQLabel continueL;
	public WhileStmt(Expression exp, Statement seq) {
		this.exp = exp;
		this.seq = seq;
	}

	@Override
	public String toString() {
		return "<WhileStmt>\n" + "<exp>\n" + exp + "\n</exp>\n" + "<seq>\n"
				+ seq + "\n</seq>\n" + "</WhileStmt>";
	}

	@Override
	public void typeCheck(Type type) {
		Type typeExp = exp.typeCheck();
		if (typeExp != Type.ERROR && typeExp != Type.BOOLEAN) {
			System.out.println("invalid type expression in condition");
			SymbolTable.errors++;
		}
		seq.typeCheck(type);
	}

	@Override
	public Boolean isReturned() {
		return false;
	}

	public Boolean hasCtrlFlow() {
		return false;
	}

	@Override
	public void genCode() {
		exp.trueL = EQLabel.FALL;
		exp.falseL = (this.next.equals(EQLabel.FALL))? new EQLabel(): this.next;
		if (EQLabel.pending() == null) {
			this.seq.next = new EQLabel();
			EQLabel.useLabel(this.seq.next);
		} else {
			this.seq.next = EQLabel.pending();
		}
		breakL = exp.falseL;
		continueL = seq.next;
		exp.genCode();
		seq.genCode();
		Node.icg.gen(Quadruple.jump(seq.next));
		if (this.next == EQLabel.FALL) {
			EQLabel.useLabel(exp.falseL);
		}
	}
}
